<?php
class FokiteQQLogin{
  private $mainuin = '';
  function __get($key){       
   return $GLOBALS['mc']->get($this->mainuin.'_'.$key);	
  }
  
  function __set($key,$value){
   $GLOBALS['mc']->set($this->mainuin.'_'.$key,$value);
  }
  
  function __construct($uin,$password){
   $GLOBALS['mc'] = memcache_init();
   $this->mainuin = $uin;
   $this->password = $password;
  }
  
  function test(){
    return $GLOBALS['mc']->getExtendedStats('items');
  }
  
  function checkQQ(){
    $uin = $this->mainuin;
    $uin = sprintf('http://check.ptlogin2.qq.com/check?uin=%s&appid=1003903',$uin);
    $uin = $this->feach($uin);
    $uin = str_replace(array('',"'",'ptui_checkVC(',');'),'',$uin);
    $uin = explode(',',$uin);
    $this->vbyte = $uin[2];
    if($uin[0]){//抓验证码
     $this->vcodeimg = $this->feach(sprintf('http://captcha.qq.com/getimage?aid=1003903&uin=%s',$this->mainuin),
     'ptvfsession='.$this->ptvfsession.'; '
     );
     return $this->vcodeimg;
    }else{//不用验证码
     $this->vcode = $uin[1];
    }
    return $uin[0];
  }
  
  private function feach($url,$ispost=false,$header = array(),$cookiestr = '',$referer = 'http://web.qq.com/'){
  $ch = curl_init(); 
  $options = array(
          CURLOPT_URL => $url,
          CURLOPT_HEADER => true, 
          CURLOPT_POST => $ispost, 
          CURLOPT_RETURNTRANSFER => true, 
          CURLOPT_FOLLOWLOCATION => 1,
    /**
          CURLOPT_COOKIEFILE => 'saemc://'.$this->mainuin.'cookie.txt',
          CURLOPT_COOKIEJAR => 'saemc://'.$this->mainuin.'cookie.txt',
**/
          CURLOPT_REFERER => $referer
      );
    if($ispost){
    	$options[CURLOPT_POSTFIELDS] = $ispost;
    }
    if(!empty($header)){
    	$options[CURLOPT_HTTPHEADER] = $header;
    }
    
    if(empty($cookiestr)){
     $options[CURLOPT_COOKIE] = $this->cookiejar;
      if( $options[CURLOPT_COOKIE]  === false){
      	 unset($options[CURLOPT_COOKIE]);
      }else{
         $options[CURLOPT_COOKIE] = implode('; ',$options[CURLOPT_COOKIE]).'; ';
      }
    }else{
     $options[CURLOPT_COOKIE] = $cookiestr;
    }
    curl_setopt_array($ch, $options); 
    $ispost = curl_exec($ch);
    curl_close($ch);
    list($header, $referer) = explode("\r\n\r\n", $ispost);
    $this->parseCookie($header);//得到头 分析COOKIE，可以判断缓存是否存在
    //var_dump($referer);
    return $referer;
  }
  
  /**
  * 分析COOKIE
 */
  private function parseCookie($header=''){
    $match = '';
    //if( preg_match_all("/set\-cookie:([^\r\n]*)/is", $header, $match)){
    if(preg_match_all('/Set-Cookie: (.*)\b/', $header, $match)){
      if($this->cookiejar === false){
      	$this->cookiejar = $match[1];
      }else{
      	$this->cookiejar = $match[1] + $this->cookiejar ;
      }
    }
    
    if(preg_match('/Set-Cookie: ptvfsession=(\w+);/', $header, $match)){
     $this->ptvfsession = $match[1];
    }
    if(preg_match('/Set-Cookie: vfwebqq=(\w+);/', $header, $match)){
     $this->vfwebqq = $match[1];
    }
    if(preg_match('/Set-Cookie: ptwebqq=(\w+);/', $header, $match)){
     $this->ptwebqq = $match[1];
    }
    if(preg_match('/Set-Cookie: skey=(\w+);/', $header, $match)){
      $this->ptwebqq = $match[1];
    }
    (unset)$match;
    //var_dump($this->cookiejar);
    //var_dump( implode('; ',$this->cookiejar));
    //preg_match_all("/Set-Cookie:(.*?)/", $header, $match, PREG_SET_ORDER);
    //preg_match_all('/Set-Cookie: (.*)\b/', $header, $match);
    //var_dump($match);
    //var_dump($this->ptvfsession );
    // $match[1]
  }
  
  function viewVcode(){
   $imgdata = $this->vcodeimg;
   header('Content-type: image/png');
    echo $imgdata;
  }
   
  function login(){
    $url = $this->getPass($this->vbyte,$this->password,$this->vcode);
    $url = "http://ptlogin2.qq.com/login?u={$this->mainuin}&p={$url}&verifycode={$this->vcode}&webqq_type=10&remember_uin=1&login2qq=1&aid=1003903&h=1&ptredirect=0&ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=3-8-8120&mibao_css=m_webqq&t=1&g=1&u1=".urlencode('http://web.qq.com/loginproxy.html?login2qq=1&webqq_type=10');
    //var_dump(urldecode($url));
    $url = $this->feach($url);
    $url = str_replace(array('',"'",'ptuiCB(',');'),'',$url);
    $url = explode(',',$url);
    $this->uname = end($url);//名字
    // var_dump($url);
    // die();
   return $url;
  }
  
  function logOut(){
    $url = sprintf('http://d.web2.qq.com/channel/logout2?clientid=844163&psessionid=%s&vfwebqq=%s',$this->psessionid,$this->vfwebqq);
    return $this->feach($url);
 }
  
  function logininWebQQ(){
    $postdata = array('status'=>'',
      'ptwebqq'=>$this->ptwebqq,
      'passwd_sig'=>'',
      'clientid'=>'844163',
      'psessionid'=>null
      );
     $url = 'http://d.web2.qq.com/channel/login2?';
     $url = $this->feach($url,'clientid=844163&psessionid=null&r='.urlencode( json_encode( $postdata ) ) );
     $url = json_decode($url,true);//vfwebqq
     $this->vfwebqq = $url['result']['vfwebqq'];
     $this->psessionid = $url['result']['psessionid'];
     $this->port = $url['result']['port'];
     $this->index =  $url['result']['index'];
     return $url['retcode'];
  }
  
  function poll(){
    $postdata = $this->psessionid;
    if($postdata === FALSE){return $postdata;}
        $postdata = array(
        'clientid'=>'844163',
        'psessionid'=>$postdata,
        'key'=>0,
        'ids'=>array()
        );
    $url = 'http://d.web2.qq.com/channel/poll2?';
    $url = $this->feach($url,'clientid=844163&psessionid='.$postdata['psessionid'].'&r='.urlencode( json_encode( $postdata ) ) );
    $this->putMsg($url);
   return $url;
  }
  
  /**
  * 解析消息
  */
  private function putMsg($strmsg = ''){
    if(empty($strmsg)){ return $strmsg;}
    $strmsg = json_decode($strmsg,TRUE);
    if(!isset($strmsg['result']) or !is_array($strmsg)){return '';}
    $msgcount = $GLOBALS['mc']->get($this->mainuin.'_msgcount');//取消息总数
    if($msgcount === FALSE){ $GLOBALS['mc']->set($this->mainuin.'_msgcount',0);}//不存在设置消息总数 
    foreach ($strmsg['result'] as $result){
        $GLOBALS['mc']->increment($this->mainuin.'_msgcount');//增加一次消息记录计数
        $GLOBALS['mc']->set($this->mainuin.'_content_'.++$msgcount,$result);//放进单个消息
        switch ( strtolower($result['poll_type']) ) {
            case 'kick_message':
                break;
            case 'buddies_status_change':
                break;
            case 'group_message':
                break;
            case 'message':
                break;
            case 'system_message':
                break;
            case 'file_message':
                break;
            case 'shake_message':
                break;
            case 'input_notify':
                break;
            case 'push_offfile':
                break;
            default: //tips //视频
                break;
        }
    }
  }
  
  /**
  *改变在线状态
 */
  function changerStatus($newstatus = 'online'){
    $newstatus = array(
    	'newstatus'=>$newstatus,
        'clientid'=>'844163',
        'psessionid'=>$this->psessionid
    );
    $newstatus = 'http://d.web2.qq.com/channel/change_status2?'.http_build_query($newstatus);
    return $this->feach($newstatus);
   }
  
    function encryptQQWebMd5($p) {
      $md5hex=md5($p);
      $len=strlen($md5hex)/2;
      $md5raw="";
      for($i=0;$i<$len;$i++) { 
        $s =  chr(hexdec(substr($md5hex,$i*2,2)));
        $s= '\x'.substr(chunk_split(bin2hex($s), 2, '\x'),0,-2); 
        $md5raw.= $s; 
      }
    return $md5raw;
  }
  
//获取QQ号密码
  function getPass($vbyte,$pass,$verify){
   $I = $this->encryptQQWebMd5($pass);
     eval('$I = "' . $I . '";');
     eval('$vbyte = "' . $vbyte . '";'); 
     $ih = $I.$vbyte;
     $H = strtoupper(md5($ih));
     $G = md5($H.strtoupper($verify));
     $G = strtoupper($G);
     return $G;
  }
  
  //C# 里面的 getAscii函数
  function ConvertToASCII($string){
    $string = str_split($string);
    return array_map('ord',$string );
   }
 
 //C# 里面的转byte数组 
   function ConvertToByte($string){
   $len=strlen($string)/2;
  $md5raw='';
  for($i=0;$i<$len;$i++) {
  $md5raw=$md5raw . chr(hexdec(substr($md5hex,$i*2,2)));
  } 
  return $md5raw;
  }
  
  function EncyptMD5Bytes($string){   
  $md5hex=md5($string);
  $md5hex = ConvertToByte($md5hex);
  return $md5hex;
    
  }
  
}

   
$qqmumber = 'QQ号码：http://weibo.com/fokite';
$qq = new FokiteQQLogin($qqmumber,'密码');

if(strcasecmp($_GET['action'],'login') === 0){
  $qq->checkQQ();
  $qq->login();
  $qq->logininWebQQ();
}

if(strcasecmp($_GET['action'], 'test') === 0){
    $values = $GLOBALS['mc']->get($qqmumber.'_msgcount');
    if($values === FALSE){
        $GLOBALS['mc']->add($qqmumber.'_msgcount',0);
    }
    $GLOBALS['mc']->increment($qqmumber.'_msgcount');
    var_dump($values);
}

if(strcasecmp($_GET['action'],'status') === 0){
    echo $qq->changerStatus($_GET['c']);
}

if(strcasecmp($_GET['action'],'logout') === 0){
  $qq->logOut();
}

if(strcasecmp($_GET['action'], 'poll') === 0){
  $qq->poll();
}

if(strcasecmp($_GET['action'], 'show') === 0){
     echo '消息个数',$qq->msgcount;
     echo '<br />';
     for($i=0;$i<=$qq->msgcount;$i++){
         var_dump($GLOBALS['mc']->get($qqmumber.'_content_'.$i));
         $GLOBALS['mc']->delete($qqmumber.'_content_'.$i);
         echo '<br />';
         $GLOBALS['mc']->decrement($qqmumber.'_msgcount');
     }
}


?>
